#ifndef FILEUTIL
#define FILEUTIL

#include <iostream>
#include <string>
#include <sys/types.h>
#include <experimental/filesystem>
#include <sys/stat.h>
#include <unistd.h>
#include <fstream>
#include <sstream>
#include "bundle.h"

//typedef ;
namespace bucai
{
    namespace fs = std::experimental::filesystem;
    class fileUtil
    {
    private:
        std::string _filename;

        struct stat _stat; // 系统文件接口 Linux和win平台都有内置

    public:
        fileUtil(const std::string &name) : _filename(name)
        {
            stat(_filename.c_str(), &_stat);
        }
        size_t FileSize()
        {
            // return fs::file_size(_p1);
            return _stat.st_size;
        }
        time_t LastATime()
        {
            return _stat.st_atime; // 系统文件接口 Linux和win平台都有内置
        }
        time_t LastMTime()
        {
            // return fs::last_write_time(_p1); //C++17文件类
            return _stat.st_mtime;
        }
        std::string FileName()
        {

            int num = _filename.find_last_of('/');
            std::string name = _filename.substr(num + 1);
            return name;
        }
        bool GetPosLen(std::string *content, size_t pos, size_t len)
        { // 读取文件pos位置，len长度
            std::ifstream ifs;
            ifs.open(_filename, std::ios::binary);
            ifs.seekg(pos, std::ios::beg);

            if (FileSize() == 0)
            {
                std::cout << "file not exist" << std::endl;
                ifs.close();
                return false;
            }

            content->resize(len);
            ifs.read(&(*content)[0], len);

            ifs.close();
            return true;
        }
        bool GetContent(std::string *content)
        { // 读取文件全部内容
            GetPosLen(content, 0, FileSize());
            return true;
        }
        bool SetContent(std::string &content)
        { // 写入文件
            std::ofstream ofs;
            ofs.open(_filename, std::ios::binary);
            ofs.write(&content[0], content.size());
            ofs.close();
        }
        bool Compress(const std::string &packname)
        {
            std::ifstream ifs;
            std::string ifilename = _filename;
            std::string ofilename = packname;
            ifs.open(ifilename, std::ios::binary);

            ifs.seekg(0, std::ios::end);
            auto sz = ifs.tellg();
            ifs.seekg(0, std::ios::beg);

            std::string s1;
            s1.resize(sz);

            ifs.read(&s1[0], sz);
            std::string zip = bundle::pack(bundle::LZIP, s1);
            ifs.close();

            std::ofstream ofs;
            ofs.open(ofilename, std::ios::binary);
            ofs.write(&zip[0], zip.size());
            ofs.close();
        }

        bool UnCompress(const std::string &filename)
        {
            // 打开待解压文件
            std::ifstream ifs;
            std::string ifilename = filename;
            std::string ofilename = _filename;

            ifs.open(ifilename, std::ios::binary);
            ifs.seekg(0, std::ios::end);
            size_t sz = ifs.tellg(); // 计算出文件大小
            ifs.seekg(0, std::ios::beg);

            std::string s1;     // 创建存储带解压文件内容
            s1.resize(sz); // 重定义字符串大小，避免空间浪费
            ifs.read(&s1[0], sz);

            std::string unzip = bundle::unpack(s1); // 解压内容写入新字符串中。

            ifs.close();

            std::ofstream ofs; // 打开解压存储文件
            ofs.open(ofilename, std::ios::binary);
            ofs.write(&unzip[0], unzip.size()); // 把解压内容写入文件中
            ofs.close();
        }
        bool Exists(){
            return fs::exists(_filename);
        }
        bool CreateDirectory(){
            return fs::create_directory(_filename);
        }
        bool ScanDirectory(std::vector<std::string> *arry)
        {
            for (auto &p : fs::directory_iterator(_filename))
            {
                if (fs::is_directory(p) == true)
                {
                    continue;
                }
                // relative_path 带有路径的文件名
                arry->push_back(fs::path(p).relative_path().string());
            }
            return true;
        }
    };
}; // namespace bucai

#endif